// NO (INTER-)DEPENDENCIES!

/* List of all the "API" functions:
 * disambiguate(): see definition!
*/

/* ------------------------
| Compilation Necessities |
-------------------------*/

#include <string>

/* -----------------
| Code starts now! |
----------------- */

// Replaces all occurrences of "irritant"
// with "replacement" within all (note!)
// substrings lying between marker pairs,
// keeping in mind some inevitable (ahem)
// "hacks" (explained below).
// NOTE THAT IRRITANT MUST NOT OCCUR
// AT THE START OR END OF THE STRING
// (CAN BE "FIXED" USING A SIMPLE
// CHECK*, ALTHOUGH THIS MUST NOT
// LOGICALLY OCCUR AT ALL!).
bool quoted_replace( std::string& s, const char& marker,
		const char& irritant, const char& replacement ){

	// Tracks if we are iterating through
	// the substring between a marker pair.
	bool ongoing = false;

	for( int i = 0, l = s.length(); i < l; i++ )
		if( s.at( i ) == marker ){
			if( ongoing ) ongoing = false;
			else ongoing = true;
		}
		else if( ongoing ){
			// *Check validity of i+-1 here!
			if( s.at( i ) == irritant ){
				// Hack to avoid  replacing occurrences of irritant
				// enclosed within marker as-is, to avoid any potential
				// confusion (as safeguard for '?' in the sample log).
				if( !( s.at( i-1 ) == marker
						and s.at( i+1 ) == marker ) )
					s.at( i ) = replacement;
				else{ // <<1>> Replacing <' '> with <'???'>
					s.at( i ) = replacement; // in queries.
					s.insert( s.begin()+i+1, '?' );
					s.insert( s.begin()+i+1, '?' );
					i+=2; l+=2; // To account for
					// elongation of the string..
				}
			}
			else if( i+1 < l ){
				// Hack to prevent messing up
				// with functions-lookalikes
				// inside strings in the query
				// (not sure if necessary)...
				if( s.at( i+1 ) == '(' ){
					s.insert( s.begin()+i+1, '?' );
					i++; // Else we will keep adding
						 // question marks endlessly.
					l++; // Note the increment in
						 // the string's length!
				}
			}
		}

	if( ongoing ) return false;
	else return true;

}

// Assumes that no question-marks are allowed
// in the log other than as when surrounded by
// single quotes (yes, it's a funny looking one
// but the sample log has question-marks, but
// only as "'?'", so we chose such a hack).
// Feel free to replace the disallowed character
// by a more suitable one. Please note that this
// hack is necessary to process such column names
// ('word1 word2...') appropriately.
// Please read comment for quoted-replace too.
bool disambiguate( std::string& s, const bool& rectify = true, const char& disallowed = '?' ){

	if( rectify ){

		// The following quirks interfere with the intended usage of
		// this function, hence need to be inevitably taken care of.
		static const regex error_begin( "(^ERROR: ')", regex::icase );
		static const regex error_trail( "(' error \\^ found .*$)", regex::icase );
		static const regex cannot_temp_fix( "can't", regex::icase );
		s = regex_replace( s, error_begin, "ERROR: " );
		s = regex_replace( s, error_trail, "" );
		s = regex_replace( s, cannot_temp_fix, "can_t" );

	}

	// Currently, in instances of "xyz..." (including
	// the double quotes), xyz... is not being changed
	// (as the sample log didn't need it - and thus it
	// has NOT been well-tested in real scenarios). To
	// do so, use the code block below (instead).
	return quoted_replace( s, '\'', ' ', disallowed );

	//bool funny_quote = quoted_replace( s, '^', ' ', disallowed );
	//bool double_quote = quoted_replace( s, '\"', ' ', disallowed );
	//bool single_quote = quoted_replace( s, '\'', ' ', disallowed );
	//return ( single_quote and double_quote and funny_quote );

}
